package com.rsscollector.feedrss;

import com.rsscollector.model.RssSourceFacade;
import com.rsscollector.model.vo.RssContent;
import com.rsscollector.model.vo.RssSource;
import com.rsscollector.util.PersistenceUtil;
import com.rsscollector.util.StringUtil;
import com.sun.syndication.feed.synd.SyndEntry;
import com.sun.syndication.feed.synd.SyndFeed;
import org.apache.log4j.Logger;

import javax.persistence.EntityManager;
import javax.persistence.Query;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;

/**
 * Created by IntelliJ IDEA.
 * User: Vu Nga
 * Date: Nov 29, 2006
 * Time: 10:45:05 PM
 * To change this template use File | Settings | File Templates.
 */
public class FeedHelper {
	
	private static Logger logger = Logger.getLogger(FeedHelper.class.getName());
    
	private String url = null;
	private SyndFeed syndFeed = null;

    public FeedHelper(String url) {
    	this.url = url;
    }

    public boolean init() {
        this.syndFeed = FeedReader.readCachingFeed(url);
        return (this.syndFeed != null); 
    }
    
    /**
     * This method will remove news that existed in DB for one Feed identify. For each hour, the system
     * will update news, they will omit the news existed by check datetime published
     */
    public void removeElementExisted(RssSource source) {
        /*Get all news from starttime and endtime in DB*/
        EntityManager em = PersistenceUtil.getEntityManagerWithTX();
        Query q = em.createQuery("select max(content.publishedDate) from RssContent as content where content.rssSource = ?1");
        q.setParameter(1, source);
        Date obj = (Date) q.getSingleResult();
        if (obj != null) {
            List temp = this.syndFeed.getEntries();
            List<SyndEntry> newRss = new ArrayList<SyndEntry>();
            List listLinks = null;
            for (Object aTemp : temp) {
                SyndEntry item = (SyndEntry) aTemp;
                //news not existed
                if (item.getPublishedDate() != null) {
                    if (obj.before(item.getPublishedDate())) {
                        newRss.add(item);
                    } else { // the rest is old news
                        //do nothing
                    }
                } else { // control in case published date is null
                    Date tempDate = StringUtil.getCurrentDate();
                    if (listLinks == null) {
                        Query query =  em.createQuery("select content.link from RssContent as content where content.rssSource = ?1 ORDER BY content.createdDate desc").setParameter(1, source);
                        query.setFirstResult(0);
                        query.setMaxResults(20);
                        listLinks = query.getResultList();
                    }
                    //don't have news current day yet OR the links have not existed yet
                    if (listLinks == null || !listLinks.contains(item.getLink())) {
                        newRss.add(item);
                    } else {
                        //do nothing
                    }
                }
            }
            // set newRss into sysnFeed
            temp = null; //gabage collection
            FeedReader.sortSyndEntryOrderByPublishedDate(newRss);
//            System.out.println("Insert ---------" + source.getRssUrl() + "--------->" + newRss.size()) ;
            this.syndFeed.setEntries(newRss);
        }
    }

    /**
     * Save new feed data.
     *
     * @param rssSource
     * @return return true if exist new feed data, return false if not
     */
    public boolean saveFeedData(RssSource rssSource) {
        EntityManager em = PersistenceUtil.getEntityManagerWithTX();
        // insert new news into db
        if (this.syndFeed != null && !this.syndFeed.getEntries().isEmpty()) {
/*
            String sourceUrl = this.syndFeed.getLink();
            String imageLink;
            String data = null;
            String key = "";
            GenericParser parser = null;
            if (sourceUrl != null && !sourceUrl.equals("")) {
                try {
                    URL urlObj = new URL(sourceUrl);
                    key = urlObj.getHost();
                    parser = ParserFactory.getInstance().getParser(key);
                    if (parser != null) {
                    	data = new String(FeedReader.readFile(urlObj));
                    }
                } catch (Exception e) {
                	logger.error("Cannot get feed data at url:" + sourceUrl, e);
                    //Don't do anything, because have problem with reading url, we will read this site later
                    return false;
                }
            }
*/
            List listEntries = this.syndFeed.getEntries();
            /*recheck again by removing the item in listEntries that existed*/
            //listEntries = removeItemsExisted (listEntries);
            /*insert news*/
            SyndEntry subFeed;
            Collection<RssContent> listContent = new ArrayList<RssContent>();
            RssContent content;
            //StringBuffer newsContent = null;
            for (Object listEntry : listEntries) {
                subFeed = (SyndEntry) listEntry;
                //imageLink = ParserFactory.getImageLink(data, key, subFeed.getTitle());
                content = new RssContent();
                /*
                if (parser != null) {
                    imageLink = parser.getImageLink(data, key, subFeed);
                    content.setTitle(parser.getTitle(subFeed.getTitle()));
                    // get content of news
                    newsContent = parser.getContent(subFeed.getLink());
                } else {
                    imageLink = null;
                    content.setTitle(subFeed.getTitle());
                }
                */
                content.setTitle(subFeed.getTitle());
                content.setLink(subFeed.getLink());
                //content.setImageLink(imageLink);
                content.setPublishedDate(subFeed.getPublishedDate() == null? new Date():subFeed.getPublishedDate());
                content.setDescriptionValue(subFeed.getDescription().getValue());
                content.setDescriptionType(subFeed.getDescription().getType());
                content.setRssSource(rssSource);
                content.setCount(0);
                listContent.add(content);
                // in case we got news content, we save the news. If not, we don't send anything
                /*
                if (newsContent != null) {
                    // Save this news to DB to allow classifying news into groups
                    content.setNewsContent(newsContent.toString());
                    em.persist(content);
                    RssSourceFacade.updateNewsGroups(content);
                }
                */
            }
            rssSource.setRssContents(listContent);
            em.persist(rssSource);
        }
        PersistenceUtil.endTransaction();
        return this.syndFeed.getEntries().size() > 0;
    }

    /**
     * recheck again by removing the item in listEntries that existed
     *
     * @param listEntries
     * @return list
     */
    private List removeItemsExisted(List listEntries) {
        List list = new ArrayList();
        SyndEntry subFeed = null;
        for (Object listEntry : listEntries) {
            subFeed = (SyndEntry) listEntry;
            if (RssSourceFacade.getRssContent(subFeed.getLink()) == null) {
                list.add(subFeed);
            }
        }
        return list;
    }
}